package com.bzkj.basicinfo.service.inventory.impl;

import com.bzkj.basicinfo.domain.inventory.InventoryChangeRecord;
import com.bzkj.basicinfo.domain.inventory.SphwphRecord;
import com.bzkj.basicinfo.domain.inventory.dto.InventoryChangeQueryDto;
import com.bzkj.basicinfo.domain.inventory.vo.DrugSummaryVo;
import com.bzkj.basicinfo.domain.inventory.vo.HuoweiSummaryVo;
import com.bzkj.basicinfo.domain.inventory.vo.InventoryStatusVo;
import com.bzkj.basicinfo.mapper.inventory.InventoryChangeMapper;
import com.bzkj.basicinfo.mapper.inventory.SphwphMapper;
import com.bzkj.basicinfo.service.inventory.InventoryChangeService;
import com.bzkj.common.annotation.DataSource;
import com.bzkj.common.enums.DataSourceType;
import com.bzkj.framework.datasource.DynamicDataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 库存变更记录Service业务层处理
 * 
 * @author system
 * @date 2025-08-05
 */
@Slf4j
@Service
public class InventoryChangeServiceImpl implements InventoryChangeService {

    @Autowired
    private InventoryChangeMapper inventoryChangeMapper;

    @Autowired
    private SphwphMapper sphwphMapper;

    @Autowired
    private InventoryChangeService self;

    // 时间格式化器
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 查询货位汇总信息（默认展示sphwph所有不为0的记录状态）
     */
    @Override
    public List<HuoweiSummaryVo> selectHuoweiSummary(InventoryChangeQueryDto queryDto) {
        List<SphwphRecord> sphwphRecords;
        try {
            // 1. 从从库查询sphwph表中shl不为0的记录（方案1：自注入）
            sphwphRecords = self.selectSphwphNonZeroRecords();
        } catch (Exception e) {
            log.error("自注入方式调用失败，尝试手动切换数据源", e);
            // 方案2：手动切换数据源（备用方案）
            try {
                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
                log.info("手动切换到从库，当前数据源：{}", DynamicDataSourceContextHolder.getDataSourceType());
                sphwphRecords = sphwphMapper.selectNonZeroRecords(null);
                log.info("从从库查询到sphwph记录数量：{}", sphwphRecords.size());
            } finally {
                DynamicDataSourceContextHolder.clearDataSourceType();
            }
        }

        try {

            // 2. 从主库查询PDA_Inventory_List记录（如果指定了盘点号）
            List<InventoryChangeRecord> pdaRecords = new ArrayList<>();
            if (queryDto.getInventoryId() != null && !queryDto.getInventoryId().isEmpty()) {
                pdaRecords = selectPdaRecordsByInventoryId(queryDto.getInventoryId());
            } else {
                // 如果没有指定盘点号，查询所有PDA记录（可能需要时间范围限制）
                pdaRecords = selectAllPdaRecords(queryDto);
            }

            // 3. 分析数据并生成汇总统计
            return analyzeInventoryData(sphwphRecords, pdaRecords, queryDto);

        } catch (Exception e) {
            log.error("查询货位汇总信息失败", e);
            return new ArrayList<>();
        }
    }
    
    /**
     * 获取库存状态详细列表（默认展示sphwph所有不为0的记录及其状态）
     */
    @Override
    public List<InventoryStatusVo> selectInventoryStatusList(InventoryChangeQueryDto queryDto) {
        try {
            List<SphwphRecord> sphwphRecords = self.selectSphwphNonZeroRecords();
            // 2. 从主库查询PDA_Inventory_List记录
            List<InventoryChangeRecord> pdaRecords = new ArrayList<>();
            if (queryDto.getInventoryId() != null && !queryDto.getInventoryId().isEmpty()) {
                pdaRecords = selectPdaRecordsByInventoryId(queryDto.getInventoryId());
            } else {
                pdaRecords = selectAllPdaRecords(queryDto);
            }

            // 3. 生成详细状态列表
            List<InventoryStatusVo> statusList = generateInventoryStatusList(sphwphRecords, pdaRecords);

            // 4. 按查询条件筛选
            statusList = statusList.stream()
                .filter(status -> {
                    // 按盘点状态筛选
                    if (queryDto.getInventoryStatus() != null && !queryDto.getInventoryStatus().isEmpty()) {
                        if (!queryDto.getInventoryStatus().equals(status.getInventoryStatus())) {
                            return false;
                        }
                    }

                    // 按货位ID筛选
                    if (queryDto.getHuoweiId() != null && !queryDto.getHuoweiId().isEmpty()) {
                        if (!queryDto.getHuoweiId().equals(status.getHuoweiId())) {
                            return false;
                        }
                    }

                    // 按商品ID筛选
                    if (queryDto.getDrugId() != null && !queryDto.getDrugId().isEmpty()) {
                        if (!queryDto.getDrugId().equals(status.getDrugId())) {
                            return false;
                        }
                    }

                    // 按商品编号筛选
                    if (queryDto.getDrugCode() != null && !queryDto.getDrugCode().isEmpty()) {
                        if (status.getDrugCode() == null || !status.getDrugCode().contains(queryDto.getDrugCode())) {
                            return false;
                        }
                    }

                    // 按批号筛选
                    if (queryDto.getDrugBatchNo() != null && !queryDto.getDrugBatchNo().isEmpty()) {
                        if (status.getDrugBatchNo() == null || !status.getDrugBatchNo().contains(queryDto.getDrugBatchNo())) {
                            return false;
                        }
                    }

                    // 按变更类型筛选
                    if (queryDto.getChangeType() != null && !queryDto.getChangeType().isEmpty()) {
                        if (status.getChangeType() == null || !queryDto.getChangeType().equals(status.getChangeType())) {
                            return false;
                        }
                    }
                    // 按操作人筛选
                    if (queryDto.getUserName() != null && !queryDto.getUserName().isEmpty()) {
                        if (status.getUserName() == null || !queryDto.getUserName().equals(status.getUserName())) {
                            return false;
                        }
                    }
                    // 按变盘点日期筛选
                    if (Objects.nonNull(queryDto.getStartTime()) && Objects.nonNull(queryDto.getEndTime())) {
                        // 先检查checkTime是否为null以及变更类型是否匹配
                        if (status.getCheckTime() == null) {
                            return false;
                        }

                        try {
                            // 假设checkTime的格式为"yyyy-MM-dd HH:mm:ss"，请根据实际格式调整
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date checkDate = sdf.parse(status.getCheckTime());
                            Date endTime = queryDto.getEndTime();
                            // 将结束时间调整为当天的23:59:59
                            if (endTime != null) {
                                Calendar calendar = Calendar.getInstance();
                                calendar.setTime(endTime);
                                // 设置为当天23时59分59秒
                                calendar.set(Calendar.HOUR_OF_DAY, 23);
                                calendar.set(Calendar.MINUTE, 59);
                                calendar.set(Calendar.SECOND, 59);
                                // 可选：设置毫秒为999以覆盖更精确的时间
                                endTime = calendar.getTime();
                            }

                            // 检查checkDate是否在startTime和endTime之间
                            if (checkDate.before(queryDto.getStartTime()) || checkDate.after(endTime)) {
                                return false;
                            }
                        } catch (ParseException e) {
                            // 处理日期格式转换异常，根据业务需求决定是返回false还是抛出异常
                            log.error("日期格式转换错误: {}", status.getCheckTime(), e);
                            return false;
                        }
                    }

                    return true;
                })
                .collect(Collectors.toList());

            return statusList;

        } catch (Exception e) {
            log.error("获取库存状态详细列表失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 查询指定货位下的商品汇总信息
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public List<DrugSummaryVo> selectDrugSummary(InventoryChangeQueryDto queryDto) {
        return inventoryChangeMapper.selectDrugSummary(queryDto);
    }
    
    /**
     * 查询库存变更记录详情
     */
    @Override
    @DataSource(DataSourceType.MASTER)
    public List<InventoryChangeRecord> selectInventoryChangeList(InventoryChangeQueryDto queryDto) {
        return inventoryChangeMapper.selectInventoryChangeList(queryDto);
    }
    
    /**
     * 根据盘点号分析盘点异常情况
     */
    @Override
    public List<HuoweiSummaryVo> analyzeInventoryByInventoryId(String inventoryId, InventoryChangeQueryDto queryDto) {
        List<HuoweiSummaryVo> resultList = new ArrayList<>();

        List<SphwphRecord> sphwphRecords;
        try {
            // 1. 从从库查询sphwph表中shl不为0的记录（方案1：自注入）
            sphwphRecords = self.selectSphwphNonZeroRecords();
        } catch (Exception e) {
            log.error("自注入方式调用失败，尝试手动切换数据源", e);
            // 方案2：手动切换数据源（备用方案）
            try {
                DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name());
                log.info("手动切换到从库，当前数据源：{}", DynamicDataSourceContextHolder.getDataSourceType());
                sphwphRecords = sphwphMapper.selectNonZeroRecords(null);
                log.info("从从库查询到sphwph记录数量：{}", sphwphRecords.size());
            } finally {
                DynamicDataSourceContextHolder.clearDataSourceType();
            }
        }

        try {

            // 2. 从主库查询指定盘点号的PDA_Inventory_List记录
            List<InventoryChangeRecord> pdaRecords = selectPdaRecordsByInventoryId(inventoryId);

            // 3. 分析数据并生成汇总统计
            resultList = analyzeInventoryData(sphwphRecords, pdaRecords, queryDto);

        } catch (Exception e) {
            log.error("分析盘点数据失败", e);
        }

        return resultList;
    }
    
    /**
     * 查询sphwph表中shl不为0的记录（从库）
     */
    @Override
//    @DataSource(DataSourceType.SLAVE)
    public List<SphwphRecord> selectSphwphNonZeroRecords() {
        log.info("进入selectSphwphNonZeroRecords方法，当前数据源：{}", DynamicDataSourceContextHolder.getDataSourceType());
        List<SphwphRecord> result = sphwphMapper.selectNonZeroRecords(null);
        log.info("selectSphwphNonZeroRecords查询结果数量：{}", result.size());
        return result;
    }

    /**
     * 根据盘点号查询PDA_Inventory_List记录（主库）
     */
    @DataSource(DataSourceType.MASTER)
    private List<InventoryChangeRecord> selectPdaRecordsByInventoryId(String inventoryId) {
        InventoryChangeQueryDto queryDto = new InventoryChangeQueryDto();
        queryDto.setInventoryId(inventoryId);
        return inventoryChangeMapper.selectInventoryChangeList(queryDto);
    }

    /**
     * 查询所有PDA_Inventory_List记录（主库）
     */
    @DataSource(DataSourceType.MASTER)
    private List<InventoryChangeRecord> selectAllPdaRecords(InventoryChangeQueryDto queryDto) {
        // 如果没有指定盘点号，查询所有PDA记录（可能需要限制时间范围）
        InventoryChangeQueryDto allQueryDto = new InventoryChangeQueryDto();

        if (queryDto.getInventoryId() != null && !queryDto.getInventoryId().isEmpty()) {
            allQueryDto.setInventoryId(queryDto.getInventoryId());
            log.info("查询指定盘点号的PDA记录，盘点号：{}", allQueryDto.getInventoryId());
        } else {
            // 如果没有盘点，设置一个较大的时间范围来查询最近的PDA记录
            Date endTime = queryDto.getEndTime();
            Date startTime = queryDto.getStartTime(); // 90天前
            allQueryDto.setStartTime(startTime);
            // 将结束时间调整为当天的23:59:59
            if (endTime != null) {
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(endTime);
                // 设置为当天23时59分59秒
                calendar.set(Calendar.HOUR_OF_DAY, 23);
                calendar.set(Calendar.MINUTE, 59);
                calendar.set(Calendar.SECOND, 59);
                // 可选：设置毫秒为999以覆盖更精确的时间
                endTime = calendar.getTime();
            }
            allQueryDto.setEndTime(endTime);
            log.info("查询最近90天的所有PDA记录");
        }

        List<InventoryChangeRecord> result = inventoryChangeMapper.selectInventoryChangeList(allQueryDto);
        log.info("查询到PDA记录数量：{}", result.size());

        // 显示前几条记录的详细信息
        if (result.size() > 0) {
            log.info("PDA记录示例：");
            result.stream().limit(3).forEach(record ->
                log.info("PDA: 货位={}, 药品={}, 批号={}, 变更类型={}, 盘点号={}",
                    record.getHuoweiId(), record.getDrugId(), record.getDrugBatchNo(),
                    record.getChangeType(), record.getInventoryId())
            );
        }

        return result;
    }

    /**
     * 分析盘点数据，生成汇总统计
     */
    private List<HuoweiSummaryVo> analyzeInventoryData(List<SphwphRecord> sphwphRecords,
                                                       List<InventoryChangeRecord> pdaRecords,
                                                       InventoryChangeQueryDto queryDto) {
        Map<String, HuoweiSummaryVo> huoweiMap = new HashMap<>();

        // 创建PDA记录的快速查找Map：key = 货位ID + 药品ID + 批号
        Map<String, List<InventoryChangeRecord>> pdaMap = pdaRecords.stream()
            .collect(Collectors.groupingBy(record ->
                record.getHuoweiId() + "|" + record.getDrugId() + "|" + record.getDrugBatchNo()));

        // 分析sphwph记录
        for (SphwphRecord sphwph : sphwphRecords) {
            String huoweiId = sphwph.getUnitCode();
            String key = huoweiId + "|" + sphwph.getProductId() + "|" + sphwph.getBatchCode();

            HuoweiSummaryVo summary = huoweiMap.computeIfAbsent(huoweiId, k -> {
                HuoweiSummaryVo vo = new HuoweiSummaryVo();
                vo.setHuoweiId(k);
                vo.setDrugCount(0);
                vo.setTotalChangeCount(0);
                vo.setNormalCount(0);
                vo.setUnInventoriedCount(0);
                vo.setWrongDeliveryCount(0);
                vo.setQuantityChangeCount(0);
                vo.setLocationChangeCount(0);
                vo.setExpiryChangeCount(0);
                vo.setBatchChangeCount(0);
                vo.setOtherChangeCount(0);
                return vo;
            });

            summary.setDrugCount(summary.getDrugCount() + 1);

            if (pdaMap.containsKey(key)) {
                // sphwph有数据，PDA也有数据 - 正常盘点
                List<InventoryChangeRecord> records = pdaMap.get(key);
                summary.setNormalCount(summary.getNormalCount() + 1);
                summary.setTotalChangeCount(summary.getTotalChangeCount() + records.size());

                // 统计各种变更类型
                for (InventoryChangeRecord record : records) {
                    String changeType = record.getChangeType();
                    if ("数量更改".equals(changeType)) {
                        summary.setQuantityChangeCount(summary.getQuantityChangeCount() + 1);
                    } else if ("货位调换".equals(changeType)) {
                        summary.setLocationChangeCount(summary.getLocationChangeCount() + 1);
                    } else if ("效期更改".equals(changeType)) {
                        summary.setExpiryChangeCount(summary.getExpiryChangeCount() + 1);
                    } else if ("批号更改".equals(changeType)) {
                        summary.setBatchChangeCount(summary.getBatchChangeCount() + 1);
                    } else if ("其它信息".equals(changeType)) {
                        summary.setOtherChangeCount(summary.getOtherChangeCount() + 1);
                    }
                }
            } else {
                // sphwph有数据，PDA无数据 - 未盘点异常
                summary.setUnInventoriedCount(summary.getUnInventoriedCount() + 1);
            }
        }

        // 检查发错货异常：PDA有数据但sphwph无数据
        Set<String> sphwphKeys = sphwphRecords.stream()
            .map(record -> record.getUnitCode() + "|" + record.getProductId() + "|" + record.getBatchCode())
            .collect(Collectors.toSet());

        for (InventoryChangeRecord pdaRecord : pdaRecords) {
            String key = pdaRecord.getHuoweiId() + "|" + pdaRecord.getDrugId() + "|" + pdaRecord.getDrugBatchNo();
            if (!sphwphKeys.contains(key)) {
                String huoweiId = pdaRecord.getHuoweiId();
                HuoweiSummaryVo summary = huoweiMap.computeIfAbsent(huoweiId, k -> {
                    HuoweiSummaryVo vo = new HuoweiSummaryVo();
                    vo.setHuoweiId(k);
                    vo.setDrugCount(0);
                    vo.setTotalChangeCount(0);
                    vo.setNormalCount(0);
                    vo.setUnInventoriedCount(0);
                    vo.setWrongDeliveryCount(0);
                    vo.setQuantityChangeCount(0);
                    vo.setLocationChangeCount(0);
                    vo.setExpiryChangeCount(0);
                    vo.setBatchChangeCount(0);
                    vo.setOtherChangeCount(0);
                    return vo;
                });
                summary.setWrongDeliveryCount(summary.getWrongDeliveryCount() + 1);
            }
        }

        return new ArrayList<>(huoweiMap.values());
    }

    /**
     * 生成详细的库存状态列表
     */
    private List<InventoryStatusVo> generateInventoryStatusList(List<SphwphRecord> sphwphRecords,
                                                               List<InventoryChangeRecord> pdaRecords) {
        List<InventoryStatusVo> resultList = new ArrayList<>();

        // 创建PDA记录的快速查找Map：key = 货位ID + 药品ID + 批号
        Map<String, InventoryChangeRecord> pdaMap = pdaRecords.stream()
            .collect(Collectors.toMap(
                record -> record.getHuoweiId() + "|" + record.getDrugId() + "|" + record.getDrugBatchNo(),
                record -> record,
                (existing, replacement) -> existing // 如果有重复key，保留第一个
            ));

        log.info("PDA记录数量：{}，sphwph记录数量：{}", pdaRecords.size(), sphwphRecords.size());

        // 只处理sphwph记录，根据是否有对应的PDA记录来判断状态
        for (SphwphRecord sphwph : sphwphRecords) {
            String key = sphwph.getUnitCode() + "|" + sphwph.getProductId() + "|" + sphwph.getBatchCode();

            InventoryStatusVo statusVo = new InventoryStatusVo();
            statusVo.setHuoweiId(sphwph.getUnitCode());
            statusVo.setDrugId(sphwph.getProductId());
            statusVo.setDrugCode(sphwph.getProductCode());
            statusVo.setDrugBatchNo(sphwph.getBatchCode());
            statusVo.setSphwphQuantity(sphwph.getNum());

            if (pdaMap.containsKey(key)) {
                // sphwph有数据，PDA也有数据 - 正常盘点
                InventoryChangeRecord pdaRecord = pdaMap.get(key);
                statusVo.setInventoryStatus("normal");
                statusVo.setInventoryStatusDesc("正常盘点");
                statusVo.setDrugName(pdaRecord.getDrugName());
                statusVo.setChangeType(pdaRecord.getChangeType());
                statusVo.setOldValue(pdaRecord.getOldValue());
                statusVo.setNewValue(pdaRecord.getNewValue());
                statusVo.setInventoryId(pdaRecord.getInventoryId());
                statusVo.setCheckTime(pdaRecord.getCheckTime() != null ? DATE_FORMAT.format(pdaRecord.getCheckTime()) : "");
                statusVo.setUserName(pdaRecord.getUserName());
            } else {
                // sphwph有数据，PDA无数据 - 未盘点异常
                statusVo.setInventoryStatus("unInventoried");
                statusVo.setInventoryStatusDesc("未盘点");
                statusVo.setDrugName(sphwph.getProductName() != null ? sphwph.getProductName() : ""); // 使用sphwph中关联的商品名称
            }

            resultList.add(statusVo);
        }

        // 检查发错货异常：PDA有数据但sphwph无数据
        Set<String> sphwphKeys = sphwphRecords.stream()
            .map(record -> record.getUnitCode() + "|" + record.getProductId() + "|" + record.getBatchCode())
            .collect(Collectors.toSet());

        for (InventoryChangeRecord pdaRecord : pdaRecords) {
            String key = pdaRecord.getHuoweiId() + "|" + pdaRecord.getDrugId() + "|" + pdaRecord.getDrugBatchNo();
            if (!sphwphKeys.contains(key)) {
                InventoryStatusVo statusVo = new InventoryStatusVo();
                statusVo.setHuoweiId(pdaRecord.getHuoweiId());
                statusVo.setDrugId(pdaRecord.getDrugId());
                statusVo.setDrugName(pdaRecord.getDrugName());
                statusVo.setDrugBatchNo(pdaRecord.getDrugBatchNo());
                statusVo.setSphwphQuantity(null); // sphwph中没有数据
                statusVo.setInventoryStatus("wrongDelivery");
                statusVo.setInventoryStatusDesc("异常");
                statusVo.setChangeType(pdaRecord.getChangeType());
                statusVo.setOldValue(pdaRecord.getOldValue());
                statusVo.setNewValue(pdaRecord.getNewValue());
                statusVo.setInventoryId(pdaRecord.getInventoryId());
                statusVo.setCheckTime(pdaRecord.getCheckTime() != null ? DATE_FORMAT.format(pdaRecord.getCheckTime()) : "");
                statusVo.setUserName(pdaRecord.getUserName());

                resultList.add(statusVo);
                log.debug("发现发错货记录：{}", key);
            }
        }

        log.info("生成状态列表完成，总记录数：{}", resultList.size());
        return resultList;
    }
}
